package com.lge.pitchingcoins.util.sessions;

import android.content.Context;
import android.net.nsd.NsdManager;
import android.net.nsd.NsdServiceInfo;

import com.lge.pitchingcoins.ui.clients.GameConnectForClientsActivity;
import com.lge.pitchingcoins.ui.clients.layer.GamePlayForClientsLayer;
import com.lge.pitchingcoins.util.PitchingCoinsLog;
import com.lge.pitchingcoins.util.Util;

public class ServiceHelper {
    public static final String SERVICE_TYPE = "_pitchingcoins._tcp.";

    private Context mContext = null;

    private NsdManager mNsdManager = null;
    private NsdManager.ResolveListener mResolveListener = null;
    private NsdManager.DiscoveryListener mDiscoveryListener = null;
    private NsdManager.RegistrationListener mRegistrationListener = null;

    private String mServiceName = null;

    private NsdServiceInfo mService = null;

    private GamePlayForClientsLayer callback = null;


    // Constructors
    public ServiceHelper(Context context) {
        mContext = context;

        mServiceName = Util.getDeviceName(context.getContentResolver());
        mNsdManager = (NsdManager)context.getSystemService(Context.NSD_SERVICE);
    }


    // Getters and Setters
    public GamePlayForClientsLayer getCallback() {
        return callback;
    }

    public void setCallback(GamePlayForClientsLayer callback) {
        this.callback = callback;
    }


    // Member Methods
    public void initializeNsd() {
        initializeResolveListener();
        initializeDiscoveryListener();
        initializeRegistrationListener();
    }

    public void initializeResolveListener() {
        mResolveListener = new NsdManager.ResolveListener() {
            @Override
            public void onServiceResolved(NsdServiceInfo serviceInfo) {
                if (callback != null) {
                    callback.onServiceResolved(serviceInfo);
                }
            }

            @Override
            public void onResolveFailed(NsdServiceInfo serviceInfo, int errorCode) {
                PitchingCoinsLog.e("Resolve failed" + errorCode);
            }
        };
    }

    public void initializeDiscoveryListener() {
        mDiscoveryListener = new NsdManager.DiscoveryListener() {
            @Override
            public void onStopDiscoveryFailed(String serviceType, int errorCode) {
                PitchingCoinsLog.e("Discovery failed: Error code:" + errorCode);
                if (mNsdManager != null) {
                    mNsdManager.stopServiceDiscovery(this);
                } else {
                    PitchingCoinsLog.d("NsdManager is null");
                }
            }

            @Override
            public void onStartDiscoveryFailed(String serviceType, int errorCode) {
                PitchingCoinsLog.e("Discovery failed: Error code:" + errorCode);
                if (mNsdManager != null) {
                    mNsdManager.stopServiceDiscovery(this);
                } else {
                    PitchingCoinsLog.d("NsdManager is null");
                }
            }

            @Override
            public void onServiceLost(NsdServiceInfo serviceInfo) {
                if (callback != null) {
                    callback.onServiceLost(serviceInfo);
                }
            }

            @Override
            public void onServiceFound(NsdServiceInfo serviceInfo) {
                PitchingCoinsLog.d("Service Found");

                if (callback != null) {
                    callback.onServiceFound(serviceInfo);
                }
            }

            @Override
            public void onDiscoveryStopped(String serviceType) {
                PitchingCoinsLog.i("Discovery stopped: " + serviceType);
            }

            @Override
            public void onDiscoveryStarted(String serviceType) {
                PitchingCoinsLog.d("Service discovery started!");
            }
        };
    }

    public void initializeRegistrationListener() {
        mRegistrationListener = new NsdManager.RegistrationListener() {
            @Override
            public void onUnregistrationFailed(NsdServiceInfo serviceInfo, int errorCode) {

            }

            @Override
            public void onServiceUnregistered(NsdServiceInfo serviceInfo) {

            }

            @Override
            public void onServiceRegistered(NsdServiceInfo serviceInfo) {
                mServiceName = serviceInfo.getServiceName();
            }

            @Override
            public void onRegistrationFailed(NsdServiceInfo serviceInfo, int errorCode) {

            }
        };
    }


    // Member Methods
    public void registerService(int port) {
        NsdServiceInfo serviceInfo = new NsdServiceInfo();
        serviceInfo.setPort(port);
        serviceInfo.setServiceName(mServiceName);
        serviceInfo.setServiceType(SERVICE_TYPE);

        mNsdManager.registerService(serviceInfo, NsdManager.PROTOCOL_DNS_SD, mRegistrationListener);
    }

    public void discoverServices() {
        mNsdManager.discoverServices(SERVICE_TYPE, NsdManager.PROTOCOL_DNS_SD, mDiscoveryListener);
    }

    public void stopDiscovery() {
        mNsdManager.stopServiceDiscovery(mDiscoveryListener);
    }

    public void reloveService(NsdServiceInfo serviceInfo) {
        mNsdManager.resolveService(serviceInfo, mResolveListener);
    }

    public NsdServiceInfo getChosenServiceInfo() {
        return mService;
    }

    public void tearDown() {
        mNsdManager.unregisterService(mRegistrationListener);
    }
}